/**
 * @file      auth_manager.c
 * @brief
 * @version   1.0
 * @date      2023.12.14
 *
 * @copyright Copyright (c) 2018 UCchip Technology Co.,Ltd. All rights reserved.
 *
 * Change Logs:
 * Date          Author       Notes
 * 2023.12.14    ucchip       the first version
 *
 */

#include "auth_manager.h"
#include "config_api.h"
#include "manager_list.h"
#include "uc_log.h"
#include "userid_manager.h"
#include <rtthread.h>
#include <string.h>

manager_list_t g_auth_list[AUTH_LIST_LEN];

manager_list_t *get_auth_list(void)
{
    return g_auth_list;
}

int manager_init_auth(void)
{
    int i = 0;

    // 遍历g_auth_list数组，初始化每一个g_auth_list元素
    for (i = 0; i < AUTH_LIST_LEN; i++)
        init_manager_list(&g_auth_list[i]);

    return 0;
}

int manager_check_key(char *key)
{
    gw_auth_cfg_t *auth_cfg = uc_static_get_gateway_auth_cfg();

    // 比较传入的key和获取的key是否相等
    if (0 != rt_strncmp(key, auth_cfg->key, sizeof(auth_cfg->key)))
        return 1;

    return 0;
}

static int query_id_callback(manager_list_t *node, void *target)
{
    // 获取当前节点
    gateway_auth_node_t *data = node->data;
    // 获取目标值
    int *dev_id = target;

    // 如果目标值等于当前节点的设备ID，则返回0
    if (*dev_id == data->dev_id)
    {
        return 0;
    }

    // 否则返回1
    return 1;
}

int manager_auth_list_is_empty(void)
{
    int is_empty = 1;

    for (int i = 0; i < AUTH_LIST_LEN; i++)
    {
        if (count_manager_list(&g_auth_list[i]) > 0)
        {
            is_empty = 0;
            break;
        }
    }

    return is_empty;
}

int manager_add_trust_dev(unsigned int dev_id)
{
    manager_list_t *current_list = &g_auth_list[GET_AUTH_LIST_KEY(dev_id)];

    // check dev id list
    if (RT_NULL == query_head_list(current_list, &dev_id, query_id_callback))
    {
        gateway_auth_node_t *node = rt_malloc(sizeof(gateway_auth_node_t));
        if (RT_NULL == node)
        {
            TRACE_E("manager_add_trust_dev malloc error");
            return 1;
        }

        node->dev_id = dev_id;
        node->is_online = 1;
        node->alive_tick = rt_tick_get();

        TRACE_D("gateway add trust dev 0x%x", dev_id);
        // add dev id list
        insert_head_manager_list(current_list, node);
    }
    // else
    // {
    //     TRACE_I("gateway dev 0x%x trust\n", dev_id);
    // }

    return 0;
}

static int del_trust_dev_callback(manager_list_t *node, void *parament)
{
    int *dest_id = parament;
    int *id = node->data;

    if (*dest_id == *id)
        return 0;

    return 1;
}

int manager_del_trust_dev(unsigned int dev_id)
{
    manager_list_t *current_list = &g_auth_list[GET_AUTH_LIST_KEY(dev_id)];

    return del_manager_node(current_list, &dev_id, del_trust_dev_callback);
}

int manager_query_trust_dev(unsigned int dev_id)
{
    manager_list_t *current_list = &g_auth_list[GET_AUTH_LIST_KEY(dev_id)];
    manager_list_t *node = query_head_list(current_list, &dev_id, query_id_callback);
    gateway_auth_node_t *data = RT_NULL;

    if (RT_NULL != node)
    {
        data = node->data;
        data->is_online = 1;
        data->alive_tick = rt_tick_get(); // 更新保活tick
        return 0;
    }

    return 1;
}

void manager_clean_trust_dev(void)
{
    int i = 0;

    // init list
    for (i = 0; i < AUTH_LIST_LEN; i++)
        clean_manager_list(&g_auth_list[i]);
}

void manager_mark_dev_offline(unsigned int user_id)
{
    manager_address_t *reserve_addr = manager_query_reserve_addr_by_wiota_id(user_id);

    manager_list_t *current_list = &g_auth_list[GET_AUTH_LIST_KEY(reserve_addr->dev_id)];
    manager_list_t *node = query_head_list(current_list, &reserve_addr->dev_id, query_id_callback);
    gateway_auth_node_t *data = RT_NULL;

    if (RT_NULL != node)
    {
        data = node->data;
        data->is_online = 0;
    }
}